﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla;
using Csla.Data;
using System.Data;
using System.Data.Common;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;

namespace Asah.SiteWorx.Commerce
{
    [Serializable()]
    public class OrderList : Csla.ReadOnlyListBase<OrderList, OrderInfo>
    {

        # region Factory Methods

        public static OrderList GetOrderList()
        {
            return DataPortal.Fetch<OrderList>();
        }

        public static OrderList GetPendingOrderList()
        {
            return DataPortal.Fetch<OrderList>(new SingleCriteria<OrderList, OrderStatus>(OrderStatus.Pending));
        }

        public static OrderInfo GetOrderInfo(int orderId)
        {
            OrderList orderList = DataPortal.Fetch<OrderList>(new SingleCriteria<OrderList, int>(orderId));
            OrderInfo orderInfo = null;

            if (orderList.Count > 0)
            {
                orderInfo = orderList.Items[0];
            }
            return orderInfo;
        }
       
        private OrderList()
        {
            // require use of factory methods
        }

        #endregion

        #region Data Access

        private void DataPortal_Fetch()
        {
            Database db = DatabaseFactory.CreateDatabase("SiteWorxCommerce");
            DbCommand dbCommand = db.GetStoredProcCommand("aspnet_Orders_RetrieveOrders");
            db.AddInParameter(dbCommand, "ApplicationId", DbType.Guid, Site.GetSite().ApplicationId);

            try
            {
                using (var dr = new SafeDataReader(db.ExecuteReader(dbCommand)))
                {
                    ShipToInfo shipToInfo = null;
                    BillToInfo billToInfo = null;
                    PaymentDetailInfo paymentDetailInfo = null;
                    
                    RaiseListChangedEvents = false;
                    IsReadOnly = false;

                    while (dr.Read())
                    {
                        shipToInfo = new ShipToInfo(dr.GetInt32("OrderId"), (ShippingMethod)dr.GetInt32("ShippingMethod"),
                                                    dr.GetString("ShipToCompany"), dr.GetString("ShipToFirstName"),
                                                    dr.GetString("ShipToLastName"), dr.GetString("ShipToAddress1"),
                                                    dr.GetString("ShipToAddress2"), dr.GetString("ShipToCity"),
                                                    dr.GetString("ShipToState"), dr.GetString("ShipToZip"), dr.GetString("ShipToPhone"),
                                                    dr.GetString("ShipToPhone"));

                        billToInfo = new BillToInfo(dr.GetInt32("OrderId"), dr.GetString("BillToCompany"), dr.GetString("BillToFirstName"),
                                                    dr.GetString("BillToLastName"), dr.GetString("BillToAddress1"),
                                                    dr.GetString("BillToAddress2"), dr.GetString("BillToCity"),
                                                    dr.GetString("BillToState"), dr.GetString("BillToZip"), dr.GetString("BillToPhone"),
                                                    dr.GetString("BillToPhone"));

                        paymentDetailInfo = new PaymentDetailInfo(dr.GetInt32("OrderId"), (PaymentMethod)dr.GetInt32("PaymentMethod"),
                                                                  dr.GetString("NameOnCard"), dr.GetString("CardNumber"),
                                                                  dr.GetString("ExpirationMonth"), dr.GetString("ExpirationYear"));

                        OrderInfo info = new OrderInfo(dr.GetInt32("OrderId"), (OrderStatus)dr.GetInt32("Status"), shipToInfo,
                                                         billToInfo, paymentDetailInfo, dr.GetGuid("CreatedBy"),
                                                         dr.GetSmartDate("CreatedDate"), dr.GetGuid("LastUpdatedBy"),
                                                         dr.GetSmartDate("LastUpdatedDate"));
                        this.Add(info);
                    }
                    IsReadOnly = true;
                    RaiseListChangedEvents = true;
                }
            }
            catch (Exception ex)
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Layer Policy");
                if (rethrow)
                {
                    throw;
                }
            }

        }

        private void DataPortal_Fetch(SingleCriteria<OrderList, OrderStatus> criteria)
        {
            Database db = DatabaseFactory.CreateDatabase("SiteWorxCommerce");
            DbCommand dbCommand = db.GetStoredProcCommand("aspnet_Orders_RetrieveOrdersByStatus");
            db.AddInParameter(dbCommand, "ApplicationId", DbType.Guid, Site.GetSite().ApplicationId);
            db.AddInParameter(dbCommand, "Status", DbType.Int32, criteria.Value);

            try
            {
                using (var dr = new SafeDataReader(db.ExecuteReader(dbCommand)))
                {
                    ShipToInfo shipToInfo = null;
                    BillToInfo billToInfo = null;
                    PaymentDetailInfo paymentDetailInfo = null;

                    RaiseListChangedEvents = false;
                    IsReadOnly = false;

                    while (dr.Read())
                    {
                        shipToInfo = new ShipToInfo(dr.GetInt32("OrderId"), (ShippingMethod)dr.GetInt32("ShippingMethod"),
                                                    dr.GetString("ShipToCompany"), dr.GetString("ShipToFirstName"),
                                                    dr.GetString("ShipToLastName"), dr.GetString("ShipToAddress1"),
                                                    dr.GetString("ShipToAddress2"), dr.GetString("ShipToCity"),
                                                    dr.GetString("ShipToState"), dr.GetString("ShipToZip"), dr.GetString("ShipToPhone"),
                                                    dr.GetString("ShipToEmail"));

                        billToInfo = new BillToInfo(dr.GetInt32("OrderId"), dr.GetString("BillToCompany"), dr.GetString("BillToFirstName"),
                                                    dr.GetString("BillToLastName"), dr.GetString("BillToAddress1"),
                                                    dr.GetString("BillToAddress2"), dr.GetString("BillToCity"),
                                                    dr.GetString("BillToState"), dr.GetString("BillToZip"), dr.GetString("BillToPhone"),
                                                    dr.GetString("BillToEmail"));

                        paymentDetailInfo = new PaymentDetailInfo(dr.GetInt32("OrderId"), (PaymentMethod)dr.GetInt32("PaymentMethod"),
                                                                  dr.GetString("NameOnCard"), dr.GetString("CardNumber"),
                                                                  dr.GetString("ExpirationMonth"), dr.GetString("ExpirationYear"));

                        OrderInfo info = new OrderInfo(dr.GetInt32("OrderId"), (OrderStatus)dr.GetInt32("Status"), shipToInfo,
                                                         billToInfo, paymentDetailInfo, dr.GetGuid("CreatedBy"),
                                                         dr.GetSmartDate("CreatedDate"), dr.GetGuid("LastUpdatedBy"),
                                                         dr.GetSmartDate("LastUpdatedDate"));
                        this.Add(info);
                    }
                    IsReadOnly = true;
                    RaiseListChangedEvents = true;
                }
            }
            catch (Exception ex)
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Layer Policy");
                if (rethrow)
                {
                    throw;
                }
            }

        }

        private void DataPortal_Fetch(SingleCriteria<OrderList, int> criteria)
        {
            Database db = DatabaseFactory.CreateDatabase("SiteWorxCommerce");
            DbCommand dbCommand = db.GetStoredProcCommand("aspnet_Orders_RetrieveOrder");
            db.AddInParameter(dbCommand, "ApplicationId", DbType.Guid, Site.GetSite().ApplicationId);
            db.AddInParameter(dbCommand, "OrderId", DbType.Int32, criteria.Value);

            try
            {
                using (var dr = new SafeDataReader(db.ExecuteReader(dbCommand)))
                {
                    RaiseListChangedEvents = false;
                    IsReadOnly = false;

                    if (dr.Read())
                    {
                        ShipToInfo shipToInfo = new ShipToInfo(dr.GetInt32("OrderId"), (ShippingMethod)dr.GetInt32("ShippingMethod"),
                                                    dr.GetString("ShipToCompany"), dr.GetString("ShipToFirstName"),
                                                    dr.GetString("ShipToLastName"), dr.GetString("ShipToAddress1"),
                                                    dr.GetString("ShipToAddress2"), dr.GetString("ShipToCity"),
                                                    dr.GetString("ShipToState"), dr.GetString("ShipToZip"), dr.GetString("ShipToPhone"),
                                                    dr.GetString("ShipToEmail"));

                        BillToInfo billToInfo = new BillToInfo(dr.GetInt32("OrderId"), dr.GetString("BillToCompany"), dr.GetString("BillToFirstName"),
                                                    dr.GetString("BillToLastName"), dr.GetString("BillToAddress1"),
                                                    dr.GetString("BillToAddress2"), dr.GetString("BillToCity"),
                                                    dr.GetString("BillToState"), dr.GetString("BillToZip"), dr.GetString("BillToPhone"),
                                                    dr.GetString("BillToEmail"));

                        PaymentDetailInfo paymentDetailInfo = new PaymentDetailInfo(dr.GetInt32("OrderId"), (PaymentMethod)dr.GetInt32("PaymentMethod"),
                                                                  dr.GetString("NameOnCard"), dr.GetString("CardNumber"),
                                                                  dr.GetString("ExpirationMonth"), dr.GetString("ExpirationYear"));

                        OrderInfo info = new OrderInfo(dr.GetInt32("OrderId"), (OrderStatus)dr.GetInt32("Status"), shipToInfo,
                                                         billToInfo, paymentDetailInfo, dr.GetGuid("CreatedBy"),
                                                         dr.GetSmartDate("CreatedDate"), dr.GetGuid("LastUpdatedBy"),
                                                         dr.GetSmartDate("LastUpdatedDate"));

                        info.OrderItemList = new List<OrderItemInfo>();
                        
                        dr.NextResult();

                        while (dr.Read())
                        {
                            info.OrderItemList.Add(new OrderItemInfo(dr.GetInt32("OrderItemId"), dr.GetString("ItemNumber"),
                                                              dr.GetString("ProductTitle"), dr.GetDecimal("UnitPrice"),
                                                              dr.GetInt32("Quantity")));
                        }

                        this.Add(info);
                    }
                    IsReadOnly = true;
                    RaiseListChangedEvents = true;
                }
            }
            catch (Exception ex)
            {
                bool rethrow = ExceptionPolicy.HandleException(ex, "Data Access Layer Policy");
                if (rethrow)
                {
                    throw;
                }
            }

        }

        #endregion

    }
}
